﻿using System;
using System.Collections.Generic;
using HCI.Questionaire.Entities;
using HCI.Questionaire.EventArgument;
using HCI.Questionaire.Exceptions;

namespace HCI.Questionaire.QuestionGroup
{
    public abstract class QuestionGroupBase : IQuestionGroup
    {
        #region Feild
        protected List<Question> _QuestionList;
        protected int _currentQuestionIndex;
        #endregion

        #region IQuestionGroup Members
        public event EventHandler<HCI.Questionaire.EventArgument.QuestionIndexChangedAgrs> QuestionIndexChanged;
        public event EventHandler<ValidateConfirmationNotifyArgs> ValidateConfirmationNotify;
        public event Action<IQuestionGroup> AnswerInQuestionChanged;

        public virtual int CurrentQuestionIndex
        {
            get
            {
                return _currentQuestionIndex;
            }
        }
        public List<Question> QuestionList
        {
            get
            {
                if (_QuestionList == null)
                {
                    this._QuestionList = new List<Question>();
                    CreateQuestionInGroup();
                }

                return _QuestionList;
            }
        }

        public virtual int NextQuestion()
        {
            if (_currentQuestionIndex >= this._QuestionList.Count - 1)
                return _currentQuestionIndex;

            _currentQuestionIndex++;
            this.OnQuestionIndexChanged();
            return CurrentQuestionIndex;
        }

        public virtual int PreviousQuestion()
        {
            if (_currentQuestionIndex <= 0)
                return _currentQuestionIndex;
            _currentQuestionIndex--;
            this.OnQuestionIndexChanged();
            return CurrentQuestionIndex;
        }

        public void MoveQuestion(int index)
        {
            if (index >= 0 && index < this._QuestionList.Count)
            {
                _currentQuestionIndex = index;
                this.OnQuestionIndexChanged();
                return;
            }
            throw new QuestionaireException("Unable to move to question that specified.");
        }

        public virtual bool CanMoveNext
        {
            get { return CurrentQuestionIndex < this._QuestionList.Count - 1; }
        }

        public virtual bool CanMovePrevious
        {
            get { return CurrentQuestionIndex > 0; }
        }

        public void AddQuestion(Question question)
        {
            question.AnswerValueChange += new Action<Answer>(question_AnswerValueChange);
            this._QuestionList.Add(question);
        }

        void question_AnswerValueChange(Answer obj)
        {
           this.OnAnswerInQuestionChanged();
        }
        #endregion

        #region Method: Abstract
        public abstract string Description { get; }

        public abstract string Instruction { get; }

        public abstract string QuestionStateText { get; }

        public abstract int GroupIndex { get; }

        protected abstract List<Question> CreateQuestionInGroup();

        #endregion

        #region Method: Private
        protected void OnQuestionIndexChanged()
        {
            if (this.QuestionIndexChanged != null)
            {
                this.QuestionIndexChanged(this, new QuestionIndexChangedAgrs { CurrentQuestionIndex = CurrentQuestionIndex });
            }

        }

        protected void OnAnswerInQuestionChanged()
        {
            if (this.AnswerInQuestionChanged != null)
            {
                this.AnswerInQuestionChanged(this);
            }

        }

        protected void OnValidateConfirmationNotify(ValidateConfirmationNotifyArgs args)
        {
            if (this.ValidateConfirmationNotify != null)
            {
                this.ValidateConfirmationNotify(this, args);
            }
        }

        public virtual void ValidateConfirmation()
        {
            this.ValidateConfirmation(null);
        }

        public virtual void ValidateConfirmation(ChangeGroupCallerInfo args)
        {
            bool isComplate = false;
            int index = 0;
            try
            {
                foreach (var item in this.QuestionList)
                {
                    item.ValidateAnswer();
                    index++;
                }

                isComplate = true;
            }
            catch (AnswerInvalidException)
            {

            }

            this.OnValidateConfirmationNotify(new ValidateConfirmationNotifyArgs { FisrstProblemIndex = index, IsComplete = isComplate, SenderArgs = args });
 
        }
        public int LoadHistoryCount
        {
            get;
            set;
        }
        #endregion

        #region IQuestionGroup Members



        #endregion

        #region IQuestionGroup Members



        #endregion

        #region IQuestionGroup Members




        #endregion

        #region IQuestionGroup Members


   

        #endregion
    }
}
